"#include \"AtmosphereShadersCommon.fxh\"\n"
"\n"
"cbuffer cbPostProcessingAttribs\n"
"{\n"
"    EpipolarLightScatteringAttribs g_PPAttribs;\n"
"};\n"
"\n"
"Texture2D<float> g_tex2DCamSpaceZ;\n"
"SamplerState     g_tex2DCamSpaceZ_sampler;\n"
"\n"
"Texture2D<float4> g_tex2DSliceEndPoints;\n"
"\n"
"void GenerateCoordinateTexturePS(FullScreenTriangleVSOutput VSOut, \n"
"                                 // IMPORTANT: non-system generated pixel shader input\n"
"                                 // arguments must have the exact same name as vertex shader \n"
"                                 // outputs and must go in the same order.\n"
"\n"
"                                 out float2 f2XY      : SV_Target0,\n"
"                                 out float fCamSpaceZ : SV_Target1)\n"
"\n"
"{\n"
"    float4 f4SliceEndPoints = g_tex2DSliceEndPoints.Load( int3(VSOut.f4PixelPos.y,0,0) );\n"
"    \n"
"    // If slice entry point is outside [-1,1]x[-1,1] area, the slice is completely invisible\n"
"    // and we can skip it from further processing.\n"
"    // Note that slice exit point can lie outside the screen, if sample locations are optimized\n"
"    if (!IsValidScreenLocation(f4SliceEndPoints.xy, g_PPAttribs.f4ScreenResolution))\n"
"    {\n"
"        // Discard invalid slices\n"
"        // Such slices will not be marked in the stencil and as a result will always be skipped\n"
"        discard;\n"
"    }\n"
"\n"
"    float2 f2UV = NormalizedDeviceXYToTexUV(VSOut.f2NormalizedXY);\n"
"\n"
"    // Note that due to the rasterization rules, UV coordinates are biased by 0.5 texel size.\n"
"    //\n"
"    //      0.5     1.5     2.5     3.5\n"
"    //   |   X   |   X   |   X   |   X   |     ....       \n"
"    //   0       1       2       3       4   f2UV * f2TexDim\n"
"    //   X - locations where rasterization happens\n"
"    //\n"
"    // We need remove this offset:\n"
"    float fSamplePosOnEpipolarLine = f2UV.x - 0.5 / float(g_PPAttribs.uiMaxSamplesInSlice);\n"
"    // fSamplePosOnEpipolarLine is now in the range [0, 1 - 1/MAX_SAMPLES_IN_SLICE]\n"
"    // We need to rescale it to be in [0, 1]\n"
"    fSamplePosOnEpipolarLine *= float(g_PPAttribs.uiMaxSamplesInSlice) / (float(g_PPAttribs.uiMaxSamplesInSlice)-1.0);\n"
"    fSamplePosOnEpipolarLine = saturate(fSamplePosOnEpipolarLine);\n"
"\n"
"    // Compute interpolated position between entry and exit points:\n"
"    f2XY = lerp(f4SliceEndPoints.xy, f4SliceEndPoints.zw, fSamplePosOnEpipolarLine);\n"
"    if (!IsValidScreenLocation(f2XY, g_PPAttribs.f4ScreenResolution))\n"
"    {\n"
"        // Discard pixels that fall behind the screen\n"
"        // This can happen if slice exit point was optimized\n"
"        discard;\n"
"    }\n"
"\n"
"    // Compute camera space z for current location\n"
"    float2 f2ScreenSpaceUV = NormalizedDeviceXYToTexUV( f2XY );\n"
"    fCamSpaceZ = g_tex2DCamSpaceZ.SampleLevel(g_tex2DCamSpaceZ_sampler, f2ScreenSpaceUV, 0);\n"
"}\n"
